
#include <cstdio>
#include <BFile>
#include <BStyle>
#include <BPainter>
#include <BReadWrite>
#include <BVBoxLayout>
#include <BHBoxLayout>
#include <BGridLayout>
#include <BDockLayout>
#include <BStackLayout>
#include <BMessageBox>
#include <BSplitButton>
#include <BDrag>
#include <BCursor>
#include <BSystem>
#include <BColorDialog>
#include <BApplication>

#include <BFog>
#include <BCone>
#include <BCube>
#include <BCapsule>
#include <BCylinder>
#include <BSphere>
#include <BGeoSphere>
#include <BSurface>
#include <BTerrain>
#include <BMaterial>
#include <BBillboard>

#include "draws/DrawCapsuleHandler.h"
#include "draws/DrawConeHandler.h"
#include "draws/DrawCubeHandler.h"
#include "draws/DrawCylinderHandler.h"
#include "draws/DrawSphereHandler.h"
#include "draws/DrawGeoSphereHandler.h"
#include "draws/DrawTubeHandler.h"
#include "draws/DrawTorusHandler.h"
#include "operas/SetupOriginOpera.h"
#include "ImportDialog.h"
#include "MaterialDialog.h"
#include "MainWindow.h"

MainWindow::MainWindow()
{
	initMenus();
	_operaIndex = 0;

	_fileDialog = new FileDialog(this);
	_organizeDialog = new OrganizeDialog(this);
	_modifyDialog = new ModifyDialog(this);
	_modifyDialog->setTitle("Modify Objects");
	_modifyDialog->setSize(300);

	BHBoxLayout* buttonLayout = new BHBoxLayout();
	{
		_openButton = new BButton("open");
		_saveButton = new BButton("save");

		_importButton = new BButton("import");
		_importButton->setTips("Import models");
		_exportButton = new BButton("export");
		_exportButton->setTips("Export current object");
		_resetButton = new BButton("reset");
		_resetButton->setTips("Reset scene");
		_viewButton = new BButton("view");
		_modifyButton = new BButton("modify");

		_undoButton = new BSplitButton("Undo");
		_undoButton->setForm(Form_IconOnly);
		_redoButton = new BSplitButton("Redo");
		_redoButton->setForm(Form_IconOnly);

		_selectButton = new BButton("Select");
		_selectButton->setForm(Form_IconOnly);
		_moveButton = new BButton("Move");
		_moveButton->setForm(Form_IconOnly);
		_rotateButton = new BButton("Rotate");
		_rotateButton->setForm(Form_IconOnly);
		_scaleButton = new BButton("Scale");
		_scaleButton->setForm(Form_IconOnly);

		_drawConeButton = createButton("Cone", "draw-cone");
		_drawCubeButton = createButton("Cube", "draw-cube");
		_drawSphereButton = createButton("Sphere", "draw-sphere");
		_drawGeoSphereButton = createButton("GeoSphere", "draw-geosphere");
		_drawCylinderButton = createButton("Cylinder", "draw-cylinder");
		_drawCapsuleButton = createButton("Capsule", "draw-capsule");
		_drawTubeButton = createButton("Tube", "draw-tube");
		_drawTorusButton = createButton("Torus", "draw-torus");
		_drawBillboardButton = createButton("Billboard", "draw-billboard");
		_drawTextualButton = createButton("Textual", "draw-textual");

		buttonLayout->addWidget(_openButton);
		buttonLayout->addWidget(_saveButton);
		buttonLayout->addSpacer(10);
		buttonLayout->addWidget(_importButton);
		buttonLayout->addWidget(_exportButton);
		buttonLayout->addWidget(_resetButton);
		buttonLayout->addWidget(_viewButton);
		buttonLayout->addWidget(_modifyButton);
		buttonLayout->addSpring(100);
		buttonLayout->addWidget(_undoButton);
		buttonLayout->addWidget(_redoButton);
		buttonLayout->addWidget(_selectButton);
		buttonLayout->addWidget(_moveButton);
		buttonLayout->addWidget(_rotateButton);
		buttonLayout->addWidget(_scaleButton);
		buttonLayout->addSpring(1000);
		buttonLayout->addWidget(_drawConeButton);
		buttonLayout->addWidget(_drawCubeButton);
		buttonLayout->addWidget(_drawSphereButton);
		buttonLayout->addWidget(_drawGeoSphereButton);
		buttonLayout->addWidget(_drawCylinderButton);
		buttonLayout->addWidget(_drawCapsuleButton);
		buttonLayout->addWidget(_drawTubeButton);
		buttonLayout->addWidget(_drawTorusButton);
		buttonLayout->addWidget(_drawBillboardButton);
		buttonLayout->addWidget(_drawTextualButton);
		buttonLayout->addSpring(1000);
		buttonLayout->setSpacing(3);
	}

	BMenu* menu = new BMenu();
	{
		_clearColorCheckBox = new BCheckBox("clear color");
		_clearColorCheckBox->setGraph(Graph_Square_Fill);
		{
			BMenu* clearColorMenu = new BMenu();
			_colorGridLayout = new BGridLayout(clearColorMenu);
			_colorGridLayout->setColumnCount(10);
			_clearColorCheckBox->setMenu(clearColorMenu);
		}
		_lightingCheckBox = new BCheckBox("lighting");
		_lightingCheckBox->setChecked(true);

		_frameCheckBox = new BCheckBox("show-frame");

		_normalsGroupBox = new BGroupBox("show-normals");
		_normalsGroupBox->setCheckable(true);
		_normalsGroupBox->setTitleAlign(Align_Center);
		{
			BRadioBox* pointNormalRadioBox = new BRadioBox("Point-Normals");
			BRadioBox* faceNormalRadioBox = new BRadioBox("Face-Normals");
			_normalLengthSlider = new BSlider();

			BVBoxLayout* vlayout = new BVBoxLayout(_normalsGroupBox);
			vlayout->addWidget(pointNormalRadioBox);
			vlayout->addWidget(faceNormalRadioBox);
			vlayout->addWidget(_normalLengthSlider);

			BButtonGroup* buttonGroup = new BButtonGroup();
			{
				buttonGroup->addButton(pointNormalRadioBox);
				buttonGroup->addButton(faceNormalRadioBox);
			}
			_normalsGroupBox->setAsset(buttonGroup);
			connect(buttonGroup, Signal_Clicked, &MainWindow::slotNormalsButtonGroupClicked);
		}

		_gridLinesGroupBox = new BGroupBox("Grid Lines");
		_gridLinesGroupBox->setCheckable(true);
		_gridLinesGroupBox->setTitleAlign(Align_Center);
		{
			BLabel* gridSizeLabel = new BLabel("Grid Size");
			_gridSizeSpinBox = new BRealSpinBox();

			BLabel* gridSectionLabel = new BLabel("Grid Section");
			_gridSegmentSpinBox = new BSpinBox();

			BLabel* gridColorLabel = new BLabel("Grid Color");
			_gridColorButton = new BButton();
			_gridColorButton->setForm(Form_IconOnly);
			_gridColorButton->setGraph(Graph_Circle_Fill);

			BGridLayout* gridLayout = new BGridLayout(_gridLinesGroupBox);
			gridLayout->addWidget(1, 0, gridSizeLabel);
			gridLayout->addWidget(1, 1, _gridSizeSpinBox);
			gridLayout->addWidget(2, 0, gridSectionLabel);
			gridLayout->addWidget(2, 1, _gridSegmentSpinBox);
			gridLayout->addWidget(3, 0, gridColorLabel);
			gridLayout->addWidget(3, 1, _gridColorButton);

			connect(_gridLinesGroupBox, Signal_Checked, &MainWindow::slotGridLineVisibleChecked);
			connect(_gridSizeSpinBox, Signal_EditFinished, &MainWindow::slotGrdiSizeEditFinished);
			connect(_gridSegmentSpinBox, Signal_EditFinished, &MainWindow::slotGridSegmentEditFinished);
			connect(_gridColorButton, Signal_Clicked, &MainWindow::slotGridColorButtonClicked);
		}

		_baseLinesGroupBox = new BGroupBox("Base Lines");
		_baseLinesGroupBox->setCheckable(true);
		_baseLinesGroupBox->setTitleAlign(Align_Center);
		{
			_baseAxisXCheckBox = new BCheckBox("Show Axis-X");
			_axisXColorButton = new BButton();
			_axisXColorButton->setForm(Form_IconOnly);
			_axisXColorButton->setGraph(Graph_Circle_Fill);

			_baseAxisYCheckBox = new BCheckBox("Show Axis-Y");
			_axisYColorButton = new BButton();
			_axisYColorButton->setForm(Form_IconOnly);
			_axisYColorButton->setGraph(Graph_Circle_Fill);

			_baseAxisZCheckBox = new BCheckBox("Show Axis-Z");
			_axisZColorButton = new BButton();
			_axisZColorButton->setForm(Form_IconOnly);
			_axisZColorButton->setGraph(Graph_Circle_Fill);

			BGridLayout* gridLayout = new BGridLayout(_baseLinesGroupBox);
			gridLayout->addWidget(1, 0, _baseAxisXCheckBox);
			gridLayout->addWidget(1, 1, _axisXColorButton);
			gridLayout->addWidget(2, 0, _baseAxisYCheckBox);
			gridLayout->addWidget(2, 1, _axisYColorButton);
			gridLayout->addWidget(3, 0, _baseAxisZCheckBox);
			gridLayout->addWidget(3, 1, _axisZColorButton);

			connect(_baseAxisXCheckBox, Signal_Checked, &MainWindow::slotBaseAxisBoxChecked);
			connect(_baseAxisYCheckBox, Signal_Checked, &MainWindow::slotBaseAxisBoxChecked);
			connect(_baseAxisZCheckBox, Signal_Checked, &MainWindow::slotBaseAxisBoxChecked);
			connect(_axisZColorButton, Signal_Clicked, &MainWindow::slotAxisColorButtonClicked);
			connect(_axisZColorButton, Signal_Clicked, &MainWindow::slotAxisColorButtonClicked);
			connect(_axisZColorButton, Signal_Clicked, &MainWindow::slotAxisColorButtonClicked);
		}

		BVBoxLayout* vlayout = new BVBoxLayout(menu);
		vlayout->addWidget(_clearColorCheckBox);
		vlayout->addWidget(_frameCheckBox);
		vlayout->addWidget(_lightingCheckBox);
		vlayout->addWidget(_normalsGroupBox);
		vlayout->addWidget(_normalLengthSlider);
		vlayout->addWidget(_gridLinesGroupBox);
		vlayout->addWidget(_baseLinesGroupBox);
	}
	_viewButton->setMenu(menu);

	_sceneTreeWidget = new BTreeWidget();
	_sceneTreeWidget->setSelectMode(Select_Multiple | Select_Continuous);

	_nameEdit = new BLineEdit(_sceneTreeWidget);
	_nameEdit->hide();

	_sceneViewer = new BViewer();
	{
		_camera = new BCamera();
		_camera->setNear(BReal(0.1));
		_camera->setFar(BReal(1000));
		_camera->setColor(0, 0, 0, 128);
		_camera->setPosition(100, 100, 100);
		_handler = new MyHandler();
		_scene = new BScene("Scene");

		_sceneViewer->setHandler(_handler);
		_sceneViewer->setCamera(_camera);
		_sceneViewer->setScene(_scene);
		_sceneTreeWidget->setAsset(_scene);

		BDockLayout* dockLayout = new BDockLayout(_sceneViewer);
		dockLayout->setSplitable(true);
		dockLayout->setSpacing(5);
		{
			_transformNote = new TransformNote();
			dockLayout->addWidget(_transformNote, Align_RightTop);

			_cameraPanel = new CameraPanel();
			_cameraPanel->setAsset(_camera);
			//_cameraPanel->setFolded(true);
			dockLayout->addWidget(_cameraPanel, Align_LeftBottom);
		}
	}
	_viewerMenu = new BMenu(_sceneViewer);

	_propertyBoard = new PropertyBoard();
	_propertyBoard->setAreaPolicy(Policy_Dynamic, Policy_Preferred);
	_propertyBoard->setSizePolicy(Policy_Preferred | Policy_Dynamic);

	BHBoxLayout* splitLayout = new BHBoxLayout();
	splitLayout->setSplitable(true);
	splitLayout->setSpacing(8);
	splitLayout->addWidget(_sceneTreeWidget, 2);
	splitLayout->addWidget(_sceneViewer, 10);
	splitLayout->addWidget(_propertyBoard, 2);

	BVBoxLayout* vlayout = new BVBoxLayout(this);
	vlayout->setSpacing(2);
	vlayout->addLayout(buttonLayout, 0);
	vlayout->addLayout(splitLayout, 100);

	connect("opera", &MainWindow::slotApplyOpera);
	connect("focus", &MainWindow::slotCameraFocus);

	connect("target-changed", &MainWindow::slotTargetSelected);
	connect("delete-target", &MainWindow::slotDeleteTarget);
	connect("focus-object", &MainWindow::slotFocusObject);
	connect("edit-material", &MainWindow::slotEditMaterial);
	connect("matrix-changed", &MainWindow::slotMatrixChanged);

	connect(_nameEdit, Signal_Focused, &MainWindow::slotNameEditFocused);

	connect(_openButton, Signal_Clicked, &MainWindow::slotOpenButtonClicked);
	connect(_saveButton, Signal_Clicked, &MainWindow::slotSaveButtonClicked);

	connect(_importButton, Signal_Clicked, &MainWindow::slotImportButtonClicked);
	connect(_exportButton, Signal_Clicked, &MainWindow::slotExportButtonClicked);
	connect(_resetButton, Signal_Clicked, &MainWindow::slotResetButtonClicked);

	connect(_undoButton, Signal_Clicked, &MainWindow::slotUndoButtonClicked);
	connect(_redoButton, Signal_Clicked, &MainWindow::slotRedoButtonClicked);
	connect(_selectButton, Signal_Clicked, &MainWindow::slotSelectButtonClicked);
	connect(_moveButton, Signal_Clicked, &MainWindow::slotMoveButtonClicked);
	connect(_rotateButton, Signal_Clicked, &MainWindow::slotRotateButtonClicked);
	connect(_scaleButton, Signal_Clicked, &MainWindow::slotScaleButtonClicked);

	connect(_frameCheckBox, Signal_Checked, &MainWindow::slotFrameChecked);
	connect(_lightingCheckBox, Signal_Checked, &MainWindow::slotLightingChecked);
	connect(_normalsGroupBox, Signal_Toggled, &MainWindow::slotShowNormalsBoxToggled);
	connect(_normalLengthSlider, Signal_Sliding, &MainWindow::slotNormalLengthEdited);
	connect(_modifyButton, Signal_Clicked, &MainWindow::slotmodifyButtonClicked);
	connect(_sceneTreeWidget, Signal_ItemClicked, &MainWindow::slotTreeItemClicked);
	connect(_sceneTreeWidget, Signal_RightClicked, &MainWindow::slotTreeRightClicked);
	connect(_sceneViewer, Signal_RightClicked, &MainWindow::slotViewerRightClicked);
	connect(_sceneViewer, Signal_DragDropped, &MainWindow::slotViewerDragDropped);
	connect(_scene, Signal_Insert, &MainWindow::slotSceneInserted);
	connect(_scene, Signal_Remove, &MainWindow::slotSceneRemoved);

	connect(_drawCapsuleButton, Signal_Toggled, &MainWindow::slotDrawCapsuleButtonToggled);
	connect(_drawConeButton, Signal_Toggled, &MainWindow::slotDrawConeButtonToggled);
	connect(_drawCubeButton, Signal_Toggled, &MainWindow::slotDrawCubeButtonToggled);
	connect(_drawCylinderButton, Signal_Toggled, &MainWindow::slotDrawCylinderButtonToggled);
	connect(_drawSphereButton, Signal_Toggled, &MainWindow::slotDrawSphereButtonToggled);
	connect(_drawTubeButton, Signal_Toggled, &MainWindow::slotDrawTubeButtonToggled);
	connect(_drawGeoSphereButton, Signal_Toggled, &MainWindow::slotDrawGeoSphereButtonToggled);
	connect(_drawTorusButton, Signal_Toggled, &MainWindow::slotDrawTorusButtonToggled);
	connect(_drawBillboardButton, Signal_Toggled, &MainWindow::slotDrawBillboardButtonToggled);
	connect(_drawTextualButton, Signal_Toggled, &MainWindow::slotDrawTextualButtonToggled);

	_gridLinesGroupBox->setChecked(_handler->gridLineVisible());
	_gridSizeSpinBox->setValue(_handler->gridSize().width());
	_gridSegmentSpinBox->setValue(_handler->gridSegment());
	_gridColorButton->setColor(_handler->gridColor());

	int visibleAxes = _handler->visibleAxes();
	_baseAxisXCheckBox->setChecked(visibleAxes & HA_X);
	_baseAxisYCheckBox->setChecked(visibleAxes & HA_Y);
	_baseAxisZCheckBox->setChecked(visibleAxes & HA_Z);

	_axisXColorButton->setColor(_handler->baseAxisXColor());
	_axisYColorButton->setColor(_handler->baseAxisYColor());
	_axisZColorButton->setColor(_handler->baseAxisZColor());

	_target = new Target(_scene);
}
MainWindow::~MainWindow()
{

}

bool MainWindow::openFile(const BString& fileName)
{
	BObjectHolder object = ReadFile(fileName);
	if (!object)
	{
		BMessageBox::Information(this, "Information", "Open file failed !");
		return false;
	}
	if (BScene* scene = object.as<BScene>())
	{
		BGroup* group = new BGroup(scene->name());
		for (int i = 0; i < scene->shapeCount(); i++)
		{
			BShape* shape = scene->shape(i);
			group->insert(shape);
		}
		for (int i = 0; i < scene->nodeCount(); i++)
		{
			BNode* node = scene->node(i);
			group->insert(node);
		}
		for (int i = 0; i < scene->groupCount(); i++)
		{
			BGroup* child = scene->group(i);
			group->insert(child);
		}
		for (int i = 0; i < scene->restraintCount(); i++)
		{
			BRestraint* restraint = scene->restraint(i);
			group->insert(restraint);
		}
		object = group;
	}
	if (BShape* shape = object.as<BShape>())
	{
		_scene->insert(shape);
		_handler->focus(shape);
		emit("target-changed", new Target(shape, _scene));
	}
	if (BNode* node = object.as<BNode>())
	{
		_scene->insert(node);
		_handler->focus(node);
		emit("target-changed", new Target(node, _scene));
	}
	if (BGroup* group = object.as<BGroup>())
	{
		_scene->insert(group);
		_handler->focus(group);
		emit("target-changed", new Target(group, _scene));
	}

	_fileName = fileName;
	BApplication::setCurrentPath(fileName.path());

	BSpace space;
	space.expand(_scene->space());
	_handler->setGridSize(space.size() * 2);

	return true;
}

void MainWindow::initMenus()
{
	_itemMenu = new BMenu();

	_createMenu = _itemMenu->addMenu("Create");
	{
		BAction* createGroupAction = _createMenu->addAction("Group");

		BMenu* createNodeMenu = _createMenu->addMenu("Node");
		{
			createNodeMenu->addAction("Node");
			createNodeMenu->addAction("Light");
			createNodeMenu->addAction("Camera");
			createNodeMenu->addAction("Fog");
		}

		BMenu* createShapeMenu = _createMenu->addMenu("Shape");
		{
			createShapeMenu->addAction("Cone");
			createShapeMenu->addAction("Cube");
			createShapeMenu->addAction("Capsule");
			createShapeMenu->addAction("Cylinder");
			createShapeMenu->addAction("Sphere");
			createShapeMenu->addAction("GeoSphere");
			createShapeMenu->addAction("Surface");
			createShapeMenu->addAction("Terrain");
			createShapeMenu->addAction("Billboard");
		}

		connect(createGroupAction, Signal_Triggered, &MainWindow::slotCreateGroupActionTriggered);
		connect(createNodeMenu, Signal_Triggered, &MainWindow::slotCreateNodeActionTriggered);
		connect(createShapeMenu, Signal_Triggered, &MainWindow::slotCreateShapeActionTriggered);
	}

	_convertMenu = _itemMenu->addMenu("Convert");
	{
		_convertMenu->addAction("to Group");
		_convertMenu->addAction("to Node");
	}

	_organizeMenu = _itemMenu->addMenu("Organize");
	{
		_organizeMenu->addAction("Group");
		_organizeMenu->addAction("Node");
	}

	_copyAction = _itemMenu->addAction("Copy");
	_cutAction = _itemMenu->addAction("Cut");
	_pasteAction = _itemMenu->addAction("Paste");
	_expandAction = _itemMenu->addAction("Expand");
	_shrinkAction = _itemMenu->addAction("Shrink");
	_renameAction = _itemMenu->addAction("Rename");
	_removeAction = _itemMenu->addAction("Remove");

	_copyAction->setShortcut("Ctrl+C");
	_cutAction->setShortcut("Ctrl+X");
	_pasteAction->setShortcut("Ctrl+V");

	_resetOriginMenu = createMenu("Reset Origin", "reset-origin");
	_resetOriginMenu->addAction(createAction("To Body Center", "to-body-center"));
	_resetOriginMenu->addAction(createAction("To Body Min", "to-body-min"));
	_resetOriginMenu->addAction(createAction("To Body Max", "to-body-max"));
	_resetOriginMenu->addAction(createAction("To Top Center", "to-top-center"));
	_resetOriginMenu->addAction(createAction("To Bottom Center", "to-bottom-center"));

	connect(_resetOriginMenu, Signal_Triggered, &MainWindow::slotResetOriginMenuTriggered);
	connect(_organizeMenu, Signal_Triggered, &MainWindow::slotOrganizeMenuTriggered);
	connect(_convertMenu, Signal_Triggered, &MainWindow::slotConvertMenuTriggered);
	connect(_copyAction, Signal_Triggered, &MainWindow::slotCopyActionTriggered);
	connect(_cutAction, Signal_Triggered, &MainWindow::slotCutActionTriggered);
	connect(_pasteAction, Signal_Triggered, &MainWindow::slotPasteActionTriggered);
	connect(_renameAction, Signal_Triggered, &MainWindow::slotRenameActionTriggered);
	connect(_removeAction, Signal_Triggered, &MainWindow::slotRemoveActionTriggered);
	connect(_expandAction, Signal_Triggered, &MainWindow::slotExpandActionTriggered);
	connect(_shrinkAction, Signal_Triggered, &MainWindow::slotShrinkActionTriggered);
}
void MainWindow::freshItemMenu()
{
	_itemMenu->clear();
	_itemMenu->addMenu(_createMenu);
	_itemMenu->addMenu(_organizeMenu);
	_itemMenu->addMenu(_convertMenu);
	const BTreeItemArray& selection = _sceneTreeWidget->selection();
	if (selection.size() > 0)
	{
		_itemMenu->addMenu(_resetOriginMenu);
		_itemMenu->addSeparator();
		_itemMenu->addAction(_copyAction);
		_itemMenu->addAction(_cutAction);
		_itemMenu->addAction(_pasteAction);
		bool expandable = false;
		bool shrinkable = false;
		for (int i = 0; i < selection.size(); i++)
		{
			if (selection[i]->childCount() > 0)
			{
				if (selection[i]->expanded())
					shrinkable = true;
				else
					expandable = true;
			}
		}
		if (shrinkable || expandable)
		{
			_itemMenu->addSeparator();
			if (expandable)
				_itemMenu->addAction(_expandAction);
			if (shrinkable)
				_itemMenu->addAction(_shrinkAction);
		}
		_itemMenu->addSeparator();
		if (selection.size() == 1)
		{
			_itemMenu->addAction(_renameAction);
		}
		_itemMenu->addAction(_removeAction);
	}
}

BMenu* MainWindow::createMenu(const BString& text, const BString& name)
{
	BMenu* menu = new BMenu(text);
	menu->setName(name);
	_menuMap[name] = menu;
	return menu;
}
BAction* MainWindow::createAction(const BString& text, const BString& name, BMenu* menu)
{
	BAction* action = new BAction(text);
	action->setName(name);
	_namedActionMap[name] = action;
	if (menu)
		menu->addAction(action);
	return action;
}
BButton* MainWindow::createButton(const BString& text, const BString& name)
{
	BButton* butotn = new BButton(text);
	butotn->setName(name);
	butotn->setForm(Form_IconOnly);
	return butotn;
}

const char* MainWindow::primName(Primitive prim)
{
	switch (prim)
	{
	case Primitive_Points:
		return "Points";
	case Primitive_Lines:
		return "Lines";
	case Primitive_LineStrip:
		return "LineStrip";
	case Primitive_LineLoop:
		return "LineLoop";
	case Primitive_Triangles:
		return "Triangles";
	case Primitive_TriangleStrip:
		return "TriangleStrip";
	case Primitive_TriangleFan:
		return "TriangleFan";
	case Primitive_Quads:
		return "Quads";
	case Primitive_QuadStrip:
		return "QuadStrip";
	case Primitive_Polygon:
		return "Polygon";
	default:
		return "None";
	}
}
BString MainWindow::findValidName(const BScene* scene, const BString& name)
{
	BString realName;
	int number = 0;
	while (number < 9999)
	{
		realName.reset();
		realName << name << number++;
		if (scene->shape(realName))
			continue;
		if (scene->node(realName))
			continue;
		if (scene->group(realName))
			continue;
		if (scene->restraint(realName))
			continue;
		break;
	}
	return realName;
}
BString MainWindow::findValidName(const BGroup* group, const BString& name)
{
	BString realName;
	int number = 0;
	while (number < 9999)
	{
		realName.reset();
		realName << name << number++;
		if (group->shape(realName))
			continue;
		if (group->node(realName))
			continue;
		if (group->child(realName))
			continue;
		if (group->restraint(realName))
			continue;
		break;
	}
	return realName;
}
BString MainWindow::findValidName(const BNode* node, const BString& name)
{
	BString realName;
	int number = 0;
	while (number < 9999)
	{
		realName.reset();
		realName << name << number++;
		if (node->shape(realName))
			continue;
		break;
	}
	return realName;
}
BIcon* MainWindow::typedIcon(const BObject* object)
{
	const BStyle* style = this->realStyle();
	for (int i = object->typeCount(); i >= 0; i--)
	{
		const BString& type = object->typeName(i);
		if (BIcon* icon = style->icon(type))
			return icon;
	}
	return 0;
}
BObject* MainWindow::copyObject(const BObject* object)
{
	if (const BShape* shape = dynamic_cast<const BShape*>(object))
	{
		return shape->clone();
	}
	if (const BNode* node = dynamic_cast<const BNode*>(object))
	{
		return node->clone();
	}
	if (const BGroup* group = dynamic_cast<const BGroup*>(object))
	{
		return group->clone();
	}
	return 0;
}
BPickHit* MainWindow::insertObject(BPickHit* hit, BObject* object)
{
	if (BShape* shape = dynamic_cast<BShape*>(object))
	{
		BPickHit* hit = new BPickHit(_scene);
		if (BNode* node = hit->node())
		{
			node->insertShape(shape);
			hit->setShape(shape);
			hit->setNode(node);
		}
		else if (BGroup* group = hit->group())
		{
			group->insert(shape);
			hit->setShape(shape);
			hit->setGroup(group);
		}
		else
		{
			_scene->insert(shape);
			hit->setShape(shape);
		}
		return hit;
	}
	if (BNode* node = dynamic_cast<BNode*>(object))
	{
		BPickHit* hit = new BPickHit(_scene);
		if (BGroup* group = hit->group())
		{
			group->insert(node);
			hit->setNode(node);
			hit->setGroup(group);
		}
		else
		{
			_scene->insert(node);
			hit->setNode(node);
		}
		return hit;
	}
	if (BGroup* group = dynamic_cast<BGroup*>(object))
	{
		BPickHit* hit = new BPickHit(_scene);
		if (BGroup* parent = hit->group())
		{
			parent->insert(group);
			hit->setGroup(group);
		}
		else
		{
			_scene->insert(group);
			hit->setGroup(group);
		}
		return hit;
	}
	if (BRestraint* restraint = dynamic_cast<BRestraint*>(object))
	{
		if (BGroup* parent = hit->group())
		{
			parent->insert(restraint);
			hit->setAsset(restraint);
			hit->setGroup(parent);
		}
		else
		{
			_scene->insert(restraint);
			hit->setAsset(restraint);
		}
		return hit;
	}
	return 0;
}
void MainWindow::transform(BGroup* group, const BVector& origin, const BQuater& quater)
{
	for (int i = 0; i < group->childCount(); i++)
	{
		BGroup* child = group->child(i);
		transform(child, origin, quater);
	}
	for (int i = 0; i < group->nodeCount(); i++)
	{
		BNode* node = group->node(i);
		BMatrix matrix = node->matrix();
		matrix.setPosition(node->position() - origin);
		BQuater rotate = matrix.rotate() * quater;
		matrix.setRotate(rotate);
		matrix.setPosition(matrix.position() + origin);
		node->setMatrix(matrix);
	}
	for (int i = 0; i < group->shapeCount(); i++)
	{
		BShape* shape = group->shape(i);
		BMatrix matrix = shape->matrix();
		matrix.setPosition(shape->position() - origin);
		BQuater rotate = matrix.rotate() * quater;
		matrix.setRotate(rotate);
		matrix.setPosition(matrix.position() + origin);
		shape->setMatrix(matrix);
	}
}
void MainWindow::collapse(BGroup* group)
{
	for (int i = 0; i < group->childCount(); i++)
	{
		BGroup* child = group->child(i);
		collapse(child);
		for (int s = 0; s < child->shapeCount(); s++)
		{
			BShape* shape = child->shape(s);
			group->insert(shape);
		}
		child->clearShapes();
	}
	group->clearChildren();
	for (int n = 0; n < group->nodeCount(); n++)
	{
		BNode* node = group->node(n);
		for (int s = 0; s < node->shapeCount(); s++)
		{
			BShape* shape = node->shape(s);
			shape->setMatrix(shape->matrix() * node->matrix());
			group->insert(shape);
		}
	}
	group->clearNodes();
}

void MainWindow::freshMenuIcons(BMenu* menu)
{
	const BStyle* style = this->realStyle();
	BString text = menu->title();
	text.lower();
	BIcon* icon = style->icon(text);
	menu->setIcon(icon);
	for (int i = 0; i < menu->count(); i++)
	{
		if (BMenu* child = menu->menu(i))
		{
			freshMenuIcons(child);
			continue;
		}
		if (BAction* action = menu->action(i))
		{
			text.reset();
			text << action->text();
			text.lower();
			BIcon* icon = style->icon(text);
			action->setIcon(icon);
			continue;
		}
	}
}
BTreeItem* MainWindow::createTreeItem(BScene* scene)
{
	BTreeItem* item = new BTreeItem(scene->name());
	item->setAsset(scene);
	item->setIcon(typedIcon(scene));
	connect(scene, Signal_Renamed, &MainWindow::slotNodeRenamed);
	for (int i = 0; i < scene->shapeCount(); i++)
	{
		BTreeItem* shapeItem = createTreeItem(scene->shape(i));
		item->addChild(shapeItem);
	}
	for (int i = 0; i < scene->nodeCount(); i++)
	{
		BTreeItem* nodeItem = createTreeItem(scene->node(i));
		item->addChild(nodeItem);
	}
	for (int i = 0; i < scene->groupCount(); i++)
	{
		BTreeItem* groupItem = createTreeItem(scene->group(i));
		item->addChild(groupItem);
	}
	for (int i = 0; i < scene->restraintCount(); i++)
	{
		BTreeItem* restraintItem = createTreeItem(scene->restraint(i));
		item->addChild(restraintItem);
	}
	return item;
}
BTreeItem* MainWindow::createTreeItem(BGroup* group)
{
	BTreeItem* item = new BTreeItem(group->name());
	item->setAsset(group);
	item->setIcon(typedIcon(group));
	connect(group, Signal_Renamed, &MainWindow::slotNodeRenamed);
	for (int i = 0; i < group->shapeCount(); i++)
	{
		BTreeItem* shapeItem = createTreeItem(group->shape(i));
		item->addChild(shapeItem);
	}
	for (int i = 0; i < group->nodeCount(); i++)
	{
		BTreeItem* nodeItem = createTreeItem(group->node(i));
		item->addChild(nodeItem);
	}
	for (int i = 0; i < group->childCount(); i++)
	{
		BTreeItem* childItem = createTreeItem(group->child(i));
		item->addChild(childItem);
	}
	for (int i = 0; i < group->restraintCount(); i++)
	{
		BTreeItem* restraintItem = createTreeItem(group->restraint(i));
		item->addChild(restraintItem);
	}
	return item;
}
BTreeItem* MainWindow::createTreeItem(BNode* node)
{
	BTreeItem* item = new BTreeItem(node->name());
	item->setAsset(node);
	item->setIcon(typedIcon(node));
	connect(node, Signal_Renamed, &MainWindow::slotNodeRenamed);
	for (int i = 0; i < node->shapeCount(); i++)
	{
		BShape* shape = node->shape(i);
		BTreeItem* shapeItem = createTreeItem(shape);
		item->addChild(shapeItem);
	}
	return item;
}
BTreeItem* MainWindow::createTreeItem(BShape* shape)
{
	BTreeItem* item = new BTreeItem(shape->name());
	item->setAsset(shape);
	item->setExpanded(false);
	item->setIcon(typedIcon(shape));
	connect(shape, Signal_Renamed, &MainWindow::slotNodeRenamed);
	if (BGeometry* geometry = dynamic_cast<BGeometry*>(shape))
	{
		for (int ei = 0; ei < geometry->elementCount(); ei++)
		{
			BElement* element = geometry->element(ei);
			BTreeItem* elementItem = item->addChild(primName(element->primitive()));
			elementItem->setAsset(element);
			elementItem->setIcon(typedIcon(element));
		}
	}
	return item;
}
BTreeItem* MainWindow::createTreeItem(BRestraint* restraint)
{
	BTreeItem* item = new BTreeItem(restraint->name());
	item->setAsset(restraint);
	item->setExpanded(false);
	item->setIcon(typedIcon(restraint));
	connect(restraint, Signal_Renamed, &MainWindow::slotNodeRenamed);
	return item;
}
void MainWindow::removeTreeItem(BTreeItem* item)
{
	if (BTreeItem* parentItem = item->parent())
	{
		if (BNode* node = parentItem->asset())
		{
			if (BShape* shape = item->asset())
				node->removeShape(shape);
		}
		else if (BGroup* group = parentItem->asset())
		{
			if (BShape* shape = item->asset())
				group->remove(shape);
			else if (BNode* node = item->asset())
				group->remove(node);
			else if (BRestraint* restraint = item->asset())
				group->remove(restraint);
			else if (BGroup* child = item->asset())
				group->remove(child);
		}
		else if (BScene* scene = parentItem->asset())
		{
			if (BShape* shape = item->asset())
				scene->remove(shape);
			else if (BNode* node = item->asset())
				scene->remove(node);
			else if (BGroup* group = item->asset())
				scene->remove(group);
			else if (BRestraint* restraint = item->asset())
				scene->remove(restraint);
		}
		parentItem->removeChild(item);
	}
	else
	{
		_sceneTreeWidget->removeItem(item);
	}
}

void MainWindow::slotOpenButtonClicked()
{
	if (_fileName.empty())
	{
		_fileDialog->setTitle("Open File");
		_fileDialog->setNameFilter("*(Scene file); *.obc");
		_fileDialog->setSelectMultiple(false);
		if (_fileDialog->execute())
		{
			const BString& fileName = _fileDialog->fileName();
			openFile(fileName);
		}
	}
}
void MainWindow::slotSaveButtonClicked()
{
	if (_fileName.empty())
	{
		_fileDialog->setTitle("Save File");
		_fileDialog->setNameFilter("*(Scene file); *.obc");
		_fileDialog->setSelectMultiple(false);
		if (_fileDialog->execute())
		{
			const BString& fileName = _fileDialog->fileName();
			if (WriteFile(fileName, _scene))
			{
				_fileName = fileName;
			}
			else
			{
				BMessageBox::Information(this, "Information", "Save file failed !");
			}
		}
	}
}
void MainWindow::slotImportButtonClicked()
{
	_fileDialog->setSelectMultiple(true);
	_fileDialog->setTitle("Import File");
	_fileDialog->setNameFilter("*(All Files); *.3ds; *.obj; *.obc; *.osc; *.stl; *.step");
	if (_fileDialog->execute())
	{
		const BStringList& fileNames = _fileDialog->fileNameList();
		if (fileNames.size() == 1 && BFile::Exist(fileNames.first()))
		{
			const BString& fileName = fileNames.first();
			BObjectHolder object = ReadFile(fileName);
			if (!object)
			{
				BMessageBox::Information(this, "Information", "Import file failed !");
				return;
			}
			if (BScene* scene = object.as<BScene>())
			{
				BGroup* group = new BGroup(scene->name());
				for (int i = 0; i < scene->shapeCount(); i++)
				{
					BShape* shape = scene->shape(i);
					group->insert(shape);
				}
				for (int i = 0; i < scene->nodeCount(); i++)
				{
					BNode* node = scene->node(i);
					group->insert(node);
				}
				for (int i = 0; i < scene->groupCount(); i++)
				{
					BGroup* child = scene->group(i);
					group->insert(child);
				}
				for (int i = 0; i < scene->restraintCount(); i++)
				{
					BRestraint* restraint = scene->restraint(i);
					group->insert(restraint);
				}
				object = group;
			}
			if (BShape* shape = object.as<BShape>())
			{
				_scene->insert(shape);
				_handler->focus(shape);
				emit("target-changed", new Target(shape, _scene));
			}
			if (BNode* node = object.as<BNode>())
			{
				_scene->insert(node);
				_handler->focus(node);
				emit("target-changed", new Target(node, _scene));
			}
			if (BGroup* group = object.as<BGroup>())
			{
				_scene->insert(group);
				_handler->focus(group);
				emit("target-changed", new Target(group, _scene));
			}
			BSpace space;
			space.expand(_scene->space());
			_handler->setGridSize(space.size() * 2);

		}
		else
		{
			ImportDialog* importDialog = new ImportDialog(this);
			importDialog->setAsset(_target);
			importDialog->setFileNames(fileNames);
			importDialog->execute();
			_handler->focus();
			const BSpace& space = _scene->space();
			BReal gridSize = (space.max() - space.min()).length() * 5;
			_handler->setGridSize(gridSize);
			this->fresh();
		}
	}
}
void MainWindow::slotExportButtonClicked()
{
	BObject* object = _scene;
	if (_sceneTreeWidget->selectedItemCount() > 1)
	{
		BGroup* group = new BGroup();
		for (int i = 0; i < _sceneTreeWidget->selectedItemCount(); i++)
		{
			BTreeItem* item = _sceneTreeWidget->selectedItem(i);
			if (BShape* shape = item->asset())
				group->insert(shape);
			else if (BNode* node = item->asset())
				group->insert(node);
			else if (BRestraint* restraint = item->asset())
				group->insert(restraint);
			else if (BGroup* child = item->asset())
				group->insert(child);
		}
		object = group;
	}
	else if (_sceneTreeWidget->selectedItemCount() == 1)
	{
		BTreeItem* item = _sceneTreeWidget->selectedItem();
		object = item->asset();
	}
	if (object == 0)
		return;
	_fileDialog->setSelectMultiple(true);
	_fileDialog->setTitle("Export File");
	_fileDialog->setNameFilter("*.obc,*.otc,*.osc,*.obj,*.3ds,*.stl;*.step");
	if(_fileDialog->execute())
	{
		const BString& fileName = _fileDialog->fileName();
		if (WriteFile(fileName, object))
		{
			BMessageBox::Information(this, "", "Export file successful !");
		}
		else
		{
			BMessageBox::Information(this, "", "Export file failed !");
		}
	}
}
void MainWindow::slotResetButtonClicked()
{
	_scene->clear();
	_sceneTreeWidget->clearItems();
	_fileName.clear();
	emit("target-changed", new Target(_scene));
}
void MainWindow::slotmodifyButtonClicked()
{
	_modifyDialog->setSceneTree(_sceneTreeWidget);
	_modifyDialog->execute();
}

void MainWindow::slotUndoButtonClicked(BObject* object, const BValue& value)
{
	_operaIndex--;
	_undoButton->setEnabled(_operaIndex > 0);
	_redoButton->setEnabled(_operaIndex < _operaStack.size());
	Opera* opera = _operaStack[_operaIndex];
	if (!opera->undo())
	{
		BMessageBox::Information(this, "Error", "Opera undo faild.");
	}
	if (_operaIndex == 0)
	{
		BString title = this->title();
		if (title.last() == '*')
		{
			title.remove('*');
			this->setTitle(title);
		}
	}
}
void MainWindow::slotRedoButtonClicked(BObject* object, const BValue& value)
{
	Opera* opera = _operaStack[_operaIndex];
	if (!opera->redo())
	{
		BMessageBox::Information(this, "Error", "Opera redo faild.");
	}
	_operaIndex++;
	_undoButton->setEnabled(_operaIndex > 0);
	_redoButton->setEnabled(_operaIndex < _operaStack.size());
}
void MainWindow::slotSelectButtonClicked()
{
	_handler->setHandleMode(HM_None);
}
void MainWindow::slotMoveButtonClicked()
{
	_handler->setHandleMode(HM_Move);
}
void MainWindow::slotRotateButtonClicked()
{
	_handler->setHandleMode(HM_Rotate);
}
void MainWindow::slotScaleButtonClicked()
{
	_handler->setHandleMode(HM_Scale);
}

void MainWindow::slotCreateGroupActionTriggered(BObject* object, const BValue& value)
{
	BAction* action = (BAction*)object;
	if (action->text() == "Group")
	{
		BGroup* group = new BGroup();
		for (int i = 0; i < _sceneTreeWidget->selectedItemCount(); i++)
		{
			BTreeItem* item = _sceneTreeWidget->selectedItem(i);
			if (BNode* node = item->asset())
			{
				group->insert(node);
				continue;
			}
			if (BGroup* child = item->asset())
			{
				group->insert(child);
				continue;
			}
		}
		if (BGroup* parent = _target->group())
		{
			group->setName(findValidName(parent, "Group"));
			parent->insert(group);
		}
		else
		{
			group->setName(findValidName(_scene, "Group"));
			_scene->insert(group);
		}
		emit("target-changed", new Target(group, _scene));
		return;
	}
}
void MainWindow::slotCreateNodeActionTriggered(BObject* object, const BValue& value)
{
	BAction* action = value;
	if (action->text() == "Node")
	{
		BNode* node = new BNode();
		for (int i = 0; i < _sceneTreeWidget->selectedItemCount(); i++)
		{
			BTreeItem* item = _sceneTreeWidget->selectedItem(i);
			if (BShape* shape = item->asset())
			{
				node->insertShape(shape);
			}
		}
		Target* target = 0;
		BTreeItem* nodeItem = createTreeItem(node);
		if (BTreeItem* parentItem = _sceneTreeWidget->selectedItem()->parent())
		{
			BString name;
			while (parentItem)
			{
				if (BScene* parentScene = parentItem->asset())
				{
					parentScene->insert(node);
					name = findValidName(parentScene, action->text());
					target = new Target(node, parentScene);
					break;
				}
				if (BGroup* parentGroup = parentItem->asset())
				{
					parentGroup->insert(node);
					name = findValidName(parentGroup, action->text());
					target = new Target(node, _scene);
					break;
				}
				parentItem = parentItem->parent();
			}
			node->setName(name);
			nodeItem->setText(name);
			parentItem->addChild(nodeItem);
		}
		else
		{
			BString name = findValidName(_scene, action->text());
			node->setName(name);
			nodeItem->setText(name);
			_sceneTreeWidget->addItem(nodeItem);
		}
		while (BTreeItem* item = _sceneTreeWidget->selectedItem())
		{
			_sceneTreeWidget->removeItem(item);
		}
		_sceneTreeWidget->scrollToItem(nodeItem);
		emit("target-changed", target);
		return;
	}
	if (action->text() == "Light")
	{

	}
	if (action->text() == "Camera")
	{

	}
	if (action->text() == "Fog")
	{
		BFog* fog = new BFog();
	}
}
void MainWindow::slotCreateShapeActionTriggered(BObject* object, const BValue& value)
{
	BAction* action = value;
	BShape* shape = 0;
	if (action->text() == "Cone")
	{
		shape = new BCone();
	}
	if (action->text() == "Cube")
	{
		shape = new BCube();
	}
	if (action->text() == "Capsule")
	{
		shape = new BCapsule();
	}
	if (action->text() == "Cylinder")
	{
		shape = new BCylinder();
	}
	if (action->text() == "Sphere")
	{
		shape = new BSphere();
	}
	if (action->text() == "GeoSphere")
	{
		shape = new BGeoSphere();
	}
	if (action->text() == "Surface")
	{
		shape = new BSurface();
	}
	if (action->text() == "Terrain")
	{
		shape = new BTerrain();
	}
	if (action->text() == "Billboard")
	{
		shape = new BBillboard();
	}
	if (shape)
	{
		shape->setName(action->text());
		_scene->insert(shape);
		BTreeItem* shapeItem = _sceneTreeWidget->addItem(shape->name());
		shapeItem->setAsset(shape);
		shapeItem->setIcon(typedIcon(shape));
		shapeItem->setExpanded(false);
		if (BGeometry* geometry = dynamic_cast<BGeometry*>(shape))
		{
			for (int ei = 0; ei < geometry->elementCount(); ei++)
			{
				BElement* element = geometry->element(ei);
				BTreeItem* elementItem = shapeItem->addChild(primName(element->primitive()));
				elementItem->setAsset(element);
				elementItem->setIcon(typedIcon(element));
			}
		}
		_handler->focus(shape);
		return;
	}
}
void MainWindow::slotOrganizeMenuTriggered(BObject* object, const BValue& value)
{
	BAction* action = value;
	if (_target.empty())
		emit("target-changed", new Target(_scene));
	if (action->text() == "Group")
	{
		BGroup* group = new BGroup();
		_organizeDialog->setTarget(_target);
		_organizeDialog->setAsset(group);
		_organizeDialog->execute();
		return;
	}
	if (action->text() == "Node")
	{
		BNode* node = new BNode();
		_organizeDialog->setTarget(_target);
		_organizeDialog->setAsset(node);
		_organizeDialog->execute();
		return;
	}
}
void MainWindow::slotConvertMenuTriggered(BObject* object, const BValue& value)
{
	BAction* action = value;
	if (BGroup* group = _target->group())
	{
		if (action->text() == "to Node")
		{
			collapse(group);
			BNode* node = new BNode(group->name());
			for (int i = 0; i < group->shapeCount(); i++)
			{
				BShape* shape = group->shape(i);
				node->insertShape(shape);
			}
			if (BGroup* parent = group->parent())
			{
				parent->remove(group);
				parent->insert(node);
			}
			else
			{
				_scene->remove(group);
				_scene->insert(node);
			}
		}
	}
}
void MainWindow::slotCutActionTriggered(BObject* object, const BValue& value)
{
	if (BShape* shape = _target->shape())
	{
		BSystem::SetClippedValue(shape);
		if (BNode* node = _target->node())
		{
			node->removeShape(shape);
		}
		else if (BGroup* group = _target->group())
		{
			group->remove(shape);
		}
		else if (BScene* scene = _target->scene())
		{
			scene->remove(shape);
		}
		return;
	}
	if (BNode* node = _target->node())
	{
		BSystem::SetClippedValue(node);
		if (BGroup* group = _target->group())
		{
			group->remove(node);
		}
		else if (BScene* scene = _target->scene())
		{
			scene->remove(node);
		}
		return;
	}
}
void MainWindow::slotCopyActionTriggered(BObject* object, const BValue& value)
{
	if (BShape* shape = _target->shape())
	{
		BShape* newShape = shape->clone();
		BSystem::SetClippedValue(newShape);
		return;
	}
	if (BNode* node = _target->node())
	{
		BNode* newNode = node->clone();
		BSystem::SetClippedValue(newNode);
		return;
	}
	if (BGroup* group = BSystem::GetClippedValue())
	{
		BGroup* newGroup = group->clone();
		BSystem::SetClippedValue(group);
		return;
	}
}
void MainWindow::slotPasteActionTriggered(BObject* object, const BValue& value)
{
	if (BShape* shape = BSystem::GetClippedValue())
	{
		if (BNode* node = _target->node())
		{
			BString name = findValidName(node, shape->name());
			shape->setName(name);
			node->insertShape(shape);
			BSystem::ClearClippedValue();
			_target->reset(shape, node);
			emit("target-changed", _target);
			return;
		}
		if (BGroup* group = _target->group())
		{
			BString name = findValidName(group, shape->name());
			shape->setName(name);
			group->insert(shape);
			BSystem::ClearClippedValue();
			_target->reset(shape, group);
			emit("target-changed", _target);
			return;
		}
		if (BScene* scene = _target->scene())
		{
			BString name = findValidName(scene, shape->name());
			shape->setName(name);
			scene->insert(shape);
			_target->reset(shape);
			emit("target-changed", _target);
			BSystem::ClearClippedValue();
			return;
		}
	}
	if (BNode* node = BSystem::GetClippedValue())
	{
		if (BGroup* group = _target->group())
		{
			BString name = findValidName(group, node->name());
			node->setName(name);
			group->insert(node);
			BSystem::ClearClippedValue();
			_target->reset(node, group);
			emit("target-changed", _target);
			return;
		}
		if (BScene* scene = _target->scene())
		{
			BString name = findValidName(scene, node->name());
			node->setName(name);
			scene->insert(node);
			BSystem::ClearClippedValue();
			_target->reset(node);
			emit("target-changed", _target);
			return;
		}
	}
	if (BGroup* group = BSystem::GetClippedValue())
	{
		if (BGroup* selectedGroup = _target->group())
		{
			BString name = findValidName(selectedGroup, group->name());
			group->setName(name);
			selectedGroup->insert(group);
			BSystem::ClearClippedValue();
			_target->reset(group);
			emit("target-changed", _target);
			return;
		}
		if (BScene* scene = _target->scene())
		{
			BString name = findValidName(scene, group->name());
			group->setName(name);
			scene->insert(group);
			BSystem::ClearClippedValue();
			_target->reset(group);
			emit("target-changed", _target);
			return;
		}
	}
}
void MainWindow::slotRenameActionTriggered(BObject* object, const BValue& value)
{
	if (BTreeItem* item = _sceneTreeWidget->selectedItem())
	{
		const BRect& crect = _sceneTreeWidget->centerRect();
		BRect textArea = item->textArea();
		textArea.right() = crect.right();
		_nameEdit->setAsset(item);
		_nameEdit->setText(item->text());
		_nameEdit->setRect(textArea);
		_nameEdit->setMinSize(48, 0);
		_nameEdit->setMaxSize(_sceneTreeWidget->centerRect().right() - textArea.left(), 9999999);
		_nameEdit->setFocused(true);
		_nameEdit->popup();
	}
}
void MainWindow::slotRemoveActionTriggered(BObject* object, const BValue& value)
{
	BTreeWidget* treeWidget = this->property("scene-tree");
	BScene* scene = _target->scene();
	for (int i = 0; i < _target->pickHitCount(); i++)
	{
		BPickHit* pickHit = _target->pickHit(i);
		if (BShape* shape = pickHit->shape())
		{
			if (BNode* node = pickHit->node())
				node->removeShape(shape);
			else if (BGroup* group = pickHit->group())
				group->remove(shape);
			else
				scene->remove(shape);
			continue;
		}
		if (BNode* node = pickHit->node())
		{
			if (BGroup* group = pickHit->group())
				group->remove(node);
			else
				scene->remove(group);
			continue;
		}
		if (BGroup* group = pickHit->group())
		{
			if (BGroup* parent = group->parent())
				parent->remove(group);
			else
				scene->remove(group);
			continue;
		}
		if (BScript* script = pickHit->asset())
		{
			if (BTreeItem* treeItem = treeWidget->itemOfAsset(pickHit->asset()))
			{
				treeWidget->removeItem(treeItem);
			}
			continue;
		}
	}
	_target->clear();
	this->post("target-changed", _target);
}
void MainWindow::slotExpandActionTriggered(BObject* object, const BValue& value)
{
	const BTreeItemArray& selection = _sceneTreeWidget->selection();
	for (int i = 0; i < selection.size(); i++)
	{
		BTreeItem* item = selection[i];
		if (item->childCount() == 0)
			continue;
		item->setExpanded(true);
	}
}
void MainWindow::slotShrinkActionTriggered(BObject* object, const BValue& value)
{
	const BTreeItemArray& selection = _sceneTreeWidget->selection();
	for (int i = 0; i < selection.size(); i++)
	{
		BTreeItem* item = selection[i];
		if (item->childCount() == 0)
			continue;
		item->setExpanded(false);
	}
}

void MainWindow::slotNameEditFocused(BObject* object, const BValue& value)
{
	if (value == false)
	{
		_nameEdit->hide();
		const BString& name = _nameEdit->text();
		BTreeItem* item = _nameEdit->asset();
		item->setText(name);
		BObject* object = item->asset();
		object->setName(name);
		_nameEdit->setAsset(BValue());
	}
}
void MainWindow::slotClearColorCheckBoxToggled(BObject* object, const BValue& value)
{
	//if (value == true)
	//{
	//	BSize hsize = _colorTableWidget->sizeHint();
	//	_colorTableWidget->setSize(hsize);
	//	_colorTableWidget->popup();
	//}
	//else
	//{
	//	_colorTableWidget->hide();
	//}
}
void MainWindow::slotClearColorButtonClicked(BObject* object, const BValue& value)
{
	BButton* button = (BButton*)object;
	const BColor& color = button->color();
	_clearColorCheckBox->setColor(color);
	_camera->setColor(color);
}

void MainWindow::slotFrameChecked()
{
	PolyMode pmode = Poly_Fill;
	if (_frameCheckBox->checked())
		pmode = Poly_Line;
	for (int i = 0; i < _scene->nodeCount(); i++)
	{
		BNode* node = _scene->node(i);
		for (int si = 0; si < node->shapeCount(); si++)
		{
			BShape* shape = node->shape(si);
			shape->setPolyMode(pmode);
		}
	}
	for (int i = 0; i < _scene->shapeCount(); i++)
	{
		BShape* shape = _scene->shape(i);
		shape->setPolyMode(pmode);
	}
	_sceneViewer->fresh();
}
void MainWindow::slotLightingChecked()
{
	bool lighting = _lightingCheckBox->checked();
	for (int i = 0; i < _scene->nodeCount(); i++)
	{
		BNode* node = _scene->node(i);
		for (int si = 0; si < node->shapeCount(); si++)
		{
			BShape* shape = node->shape(si);
			shape->setLighting(lighting);
		}
	}
	for (int i = 0; i < _scene->shapeCount(); i++)
	{
		BShape* shape = _scene->shape(i);
		shape->setLighting(lighting);
	}
	_camera->fresh();
}
void MainWindow::slotShowNormalsBoxToggled(BObject* object, const BValue& value)
{
	bool checked = value;
	_handler->setShowNormals(checked);
}
void MainWindow::slotNormalsButtonGroupClicked(BObject* object, const BValue& value)
{
	BButton* button = value;
	_handler->setNormalsFlags(button->text());
}
void MainWindow::slotNormalLengthEdited()
{
	double ratio = _normalLengthSlider->ratio();
	_handler->setNormalLengthRatio((float)ratio);
}
void MainWindow::slotGridLineVisibleChecked(BObject* object, const BValue& value)
{
	BGroupBox* groupBox = (BGroupBox*)object;
	bool visible = value;
	for (int i = 0; i < groupBox->childCount(); i++)
	{
		groupBox->child(i)->setEnabled(visible);
	}
	_handler->setGridLineVisible(visible);
}
void MainWindow::slotGrdiSizeEditFinished(BObject* object, const BValue& value)
{
	BReal gridSize = value;
	_handler->setGridSize(gridSize);
}
void MainWindow::slotGridSegmentEditFinished(BObject* object, const BValue& value)
{
	int segment = value;
	_handler->setGridSegment(segment);
}
void MainWindow::slotGridColorButtonClicked()
{
	BColor color = _gridColorButton->color();
	color = BColorDialog::ChooseColor("Choose GridLine Color", color);
	_gridColorButton->setColor(color);
	_handler->setGridColor(color);
}
void MainWindow::slotResetOriginMenuTriggered(BObject* object, const BValue& value)
{
	BAction* action = value;
	const BSpace& space = _target->box().space();
	if (action->name() == "to-body-center")
	{
		SetupOriginOpera* opera = new SetupOriginOpera(_target);
		opera->setOrigin(space.center());
		emit("opera", opera);
	}
	if (action->name() == "to-body-min")
	{
		SetupOriginOpera* opera = new SetupOriginOpera(_target);
		opera->setOrigin(space.min());
		emit("opera", opera);
	}
	if (action->name() == "to-body-max")
	{
		SetupOriginOpera* opera = new SetupOriginOpera(_target);
		opera->setOrigin(space.max());
		emit("opera", opera);
	}
	if (action->name() == "to-top-center")
	{
		SetupOriginOpera* opera = new SetupOriginOpera(_target);
		BVector center = space.center();
		center.z() = space.max().z();
		opera->setOrigin(center);
		emit("opera", opera);
	}
	if (action->name() == "to-bottom-center")
	{
		SetupOriginOpera* opera = new SetupOriginOpera(_target);
		BVector center = space.center();
		center.z() = space.min().z();
		opera->setOrigin(center);
		emit("opera", opera);
	}
}

void MainWindow::slotBaseAxisBoxChecked(BObject* object, const BValue& value)
{
	int visibleAxes = 0;
	visibleAxes |= _baseAxisXCheckBox->checked() ? HA_X : 0;
	visibleAxes |= _baseAxisYCheckBox->checked() ? HA_Y : 0;
	visibleAxes |= _baseAxisZCheckBox->checked() ? HA_Z : 0;
	_handler->setVisibleBaseAxes(visibleAxes);
}
void MainWindow::slotAxisColorButtonClicked(BButton* button, const BValue& value)
{
	const BColor& color = BColorDialog::ChooseColor(this, "Choose color for axis", button->color());
	if (button->color() != color)
	{
		button->setColor(color);
		if (button == _axisXColorButton)
			_handler->setBaseAxisXColor(color);
		if (button == _axisYColorButton)
			_handler->setBaseAxisYColor(color);
		if (button == _axisZColorButton)
			_handler->setBaseAxisZColor(color);
	}
}

void MainWindow::slotTreeItemClicked(BObject* object, const BValue& value)
{
	if (_nameEdit->asset() != value)
	{
		_nameEdit->setAsset(value);
		_nameEdit->setPos(BCursor::GetPos());
	}
	else
	{
		BTreeItem* item = value;
		bool editing = (_nameEdit->pos() - BCursor::GetPos()).length2() > 6;
		if (item && editing)
		{
			const BRect& crect = _sceneTreeWidget->centerRect();
			BRect textArea = item->textArea();
			textArea.right() = crect.right();
			if (textArea.right() >= crect.right())
				textArea.right() = crect.right() - 1;
			_nameEdit->setParent(_sceneTreeWidget);
			_nameEdit->setRect(textArea);
			_nameEdit->setText(item->text());
			_nameEdit->popup();
		}
	}
	Target* target = new Target(_scene);
	for (int i = 0; i < _sceneTreeWidget->selectedItemCount(); i++)
	{
		BTreeItem* item = _sceneTreeWidget->selectedItem(i);
		BPickHit* pickHit= new BPickHit();
		if (BScript* script = item->asset())
		{
			pickHit->setAsset(item->asset());
			if (BTreeItem* parent = item->parent())
			{
				if (BNode* node = parent->asset())
					pickHit->setNode(node);
				if (BGroup* group = parent->asset())
					pickHit->setGroup(group);
			}
		}
		else if (BShape* shape = item->asset())
		{
			pickHit->setShape(shape);
			if (BTreeItem* parent = item->parent())
			{
				if (BNode* node = parent->asset())
					pickHit->setNode(node);
				if (BGroup* group = parent->asset())
					pickHit->setGroup(group);
			}
		}
		else if (BNode* node = item->asset())
		{
			pickHit->setNode(node);
			pickHit->setGroup(node->group());
		}
		else if (BGroup* group = item->asset())
		{
			pickHit->setGroup(group);
		}
		else if (BRestraint* restraint = item->asset())
		{
			pickHit->setAsset(restraint);
		}
		target->addPickHit(pickHit);
	}
	emit("target-changed", target);
}
void MainWindow::slotTreeRightClicked(BObject* object, const BValue& value)
{
	BPoint pos = value;
	_itemMenu->setParent(_sceneTreeWidget);
	_itemMenu->setPos(pos);
	_itemMenu->popup();
}
void MainWindow::slotViewerRightClicked(BObject* object, const BValue& value)
{
	const BPoint& pos = value;
	freshItemMenu();
	_itemMenu->setParent(_sceneViewer);
	_itemMenu->setPos(pos);
	_itemMenu->popup();
}
void MainWindow::slotViewerDragDropped(BObject* object, const BValue& value)
{
	BDrag* drag = value;
	if (const BStringArray* fileNames = drag->value())
	{
		BPickHit* hit = _sceneViewer->pick(drag->pos());
		if (!hit)
			hit = new BPickHit(_scene);
		Target* target = new Target(_scene);
		for (int i = 0; i < fileNames->size(); i++)
		{
			const BString& fileName = fileNames->at(i);
			BObjectHolder obj = ReadFile(fileName);
			BPickHit* pickHit = insertObject(hit, obj);
			target->addPickHit(pickHit);
		}
		this->emit("target-changed", target);
		this->emit("focus-object", target);
	}
}

void MainWindow::slotApplyOpera(BObject* object, const BValue& value)
{
	Opera* opera = value;
	_operaStack.append(opera);
	_undoButton->setEnabled(_operaIndex > 0);
	_redoButton->setEnabled(_operaIndex < _operaStack.size());
	_redoButton->click();
}
void MainWindow::slotCameraFocus(BObject* object, const BValue& value)
{
	if (value.is<BSpace>())
	{
		const BSpace& space = value;
		_handler->focus(space);
		return;
	}
	if (value.is<BBox>())
	{
		const BBox& box = value;
		_handler->focus(box);
		return;
	}
	if (Target* target = value)
	{
		_handler->focus(target->space());
		return;
	}
	if (BObject* object = value)
	{
		_handler->focus(object);
		return;
	}
}
void MainWindow::slotTargetSelected(BObject* object, const BValue& value)
{
	_target = (Target*)value;
	BTreeItemArray selectedItems;
	if (_target && !_target->empty())
	{
		BTreeItemArray selectedItems;
		for (int i = 0; i < _target->pickHitCount(); i++)
		{
			BPickHit* hit = _target->pickHit(i);
			BString path = hit->path();
			if (BTreeItem* item = _sceneTreeWidget->locate(path))
			{
				selectedItems.append(item);
				continue;
			}
			if (BShape* shape = hit->shape())
			{
				if (BTreeItem* item = _sceneTreeWidget->itemOfAsset(shape))
					selectedItems.append(item);
				continue;
			}
			if (BNode* node = hit->node())
			{
				if (BTreeItem* item = _sceneTreeWidget->itemOfAsset(node))
					selectedItems.append(item);
				continue;
			}
			if (BGroup* group = hit->group())
			{
				if (BTreeItem* item = _sceneTreeWidget->itemOfAsset(group))
					selectedItems.append(item);
				continue;
			}
			if (BObject* object = hit->asset())
			{
				if (BTreeItem* item = _sceneTreeWidget->itemOfAsset(object))
					selectedItems.append(item);
				continue;
			}
		}
		_sceneTreeWidget->setSelection(selectedItems);
		if (BTreeItem* first = selectedItems.first())
		{
			BTreeItem* parent = first->parent();
			while (parent)
			{
				parent->setExpanded(true);
				parent = parent->parent();
			}
			if (!_sceneTreeWidget->itemVisual(first))
			{
				_sceneTreeWidget->scrollToItem(first);
			}
			if (selectedItems.size() == 1)
			{
				BTreeItem* targetItem = selectedItems.first()->root();
			}
			if (BShape* shape = _target->shape())
				_transformNote->setAsset(shape->matrix());
			else if (BNode* node = _target->node())
				_transformNote->setAsset(node->matrix());
			else
				_transformNote->setAsset(BValue());
		}
	}
	else
	{
		_sceneTreeWidget->clearSelection();
		_transformNote->setAsset(BValue());
	}
	freshItemMenu();
}
void MainWindow::slotDeleteTarget(BObject* object, const BValue& value)
{
	if (BAction* removeAction = _itemMenu->action("Remove"))
	{
		removeAction->trigger();
	}
}
void MainWindow::slotFocusObject(BObject* object, const BValue& value)
{
	if (Target* target = value)
	{
		_handler->focus(target->space());
		return;
	}
}
void MainWindow::slotEditMaterial(BObject* object, const BValue& value)
{
	static MaterialDialog* dialog = new MaterialDialog(this);
	dialog->setAsset(value);
	dialog->popup();
}
void MainWindow::slotMatrixChanged(BObject* object, const BValue& value)
{
	if (_target)
	{
		const BMatrix& matrix = value;
		if (BShape* shape = _target->shape())
			shape->setMatrix(matrix);
		else if (BNode* node = _target->node())
			node->setMatrix(matrix);
		else if (BGroup* group = _target->group())
		{
			BVector origin = group->space().center();
			transform(group, origin, matrix.rotate());
		}
	}
}

void MainWindow::slotSceneInserted(BObject* object, const BValue& value)
{
	if (BShape* shape = value)
	{
		BTreeItem* item = createTreeItem(shape);
		if (const BNode* node = value.annex<BNode>())
		{
			BTreeItem* parentItem = _sceneTreeWidget->itemOfAsset(node);
			parentItem->addChild(item);
		}
		else if (const BGroup* group = value.annex<BGroup>())
		{
			BTreeItem* parentItem = _sceneTreeWidget->itemOfAsset(group);
			parentItem->addChild(item);
		}
		else if (_scene->contain(shape))
		{
			_sceneTreeWidget->addItem(item);
		}
		return;
	}
	if (BNode* node = value)
	{
		BTreeItem* item = createTreeItem(node);
		if (BGroup* group = node->group())
		{
			BTreeItem* parentItem = _sceneTreeWidget->itemOfAsset(group);
			parentItem->addChild(item);
		}
		else
		{
			_sceneTreeWidget->addItem(item);
		}
		return;
	}
	if (BRestraint* restraint = value)
	{
		BTreeItem* item = createTreeItem(restraint);
		if (BGroup* parent = restraint->group())
		{
			BTreeItem* parentItem = _sceneTreeWidget->itemOfAsset(parent);
			parentItem->addChild(item);
		}
		else
		{
			_sceneTreeWidget->addItem(item);
		}
		return;
	}
	if (BGroup* group = value)
	{
		BTreeItem* item = createTreeItem(group);
		if (BGroup* parent = group->parent())
		{
			BTreeItem* parentItem = _sceneTreeWidget->itemOfAsset(parent);
			parentItem->addChild(item);
		}
		else
		{
			_sceneTreeWidget->addItem(item);
		}
		return;
	}
}
void MainWindow::slotSceneRemoved(BObject* object, const BValue& value)
{
	if (BTreeItem* item = _sceneTreeWidget->itemOfAsset(value))
	{
		_sceneTreeWidget->removeItem(item);
	}
}
void MainWindow::slotNodeRenamed(BObject* object, const BValue& value)
{
	const BString& name = value;
	if (BTreeItem* item = _sceneTreeWidget->itemOfAsset(object))
	{
		item->setText(name);
	}
}

void MainWindow::slotDrawConeButtonToggled(BObject* object, const BValue& value)
{
	static BHolder<DrawConeHandler> handler = new DrawConeHandler();
	if (bool checked = value)
	{
		connect(handler, Signal_Detached, &MainWindow::slotDrawHandlerDetached);
		handler->setAsset(_target);
		emit("apply-handler", handler);
	}
	else
	{
		disconnect(handler, Signal_Detached);
		handler->setAsset(BValue());
		emit("remove-handler", handler);
	}
	object->setAsset(handler);
}
void MainWindow::slotDrawCubeButtonToggled(BObject* object, const BValue& value)
{
	static BHolder<DrawCubeHandler> handler = new DrawCubeHandler();
	if (bool checked = value)
	{
		connect(handler, Signal_Detached, &MainWindow::slotDrawHandlerDetached);
		handler->setAsset(_target);
		emit("apply-handler", handler);
	}
	else
	{
		disconnect(handler, Signal_Detached);
		handler->setAsset(BValue());
		emit("remove-handler", handler);
	}
	object->setAsset(handler);
}
void MainWindow::slotDrawSphereButtonToggled(BObject* object, const BValue& value)
{
	static BHolder<DrawSphereHandler> handler = new DrawSphereHandler();
	if (bool checked = value)
	{
		connect(handler, Signal_Detached, &MainWindow::slotDrawHandlerDetached);
		handler->setAsset(_target);
		emit("apply-handler", handler);
	}
	else
	{
		disconnect(handler, Signal_Detached);
		handler->setAsset(BValue());
		emit("remove-handler", handler);
	}
	object->setAsset(handler);
}
void MainWindow::slotDrawGeoSphereButtonToggled(BObject* object, const BValue& value)
{
	static BHolder<DrawGeoSphereHandler> handler = new DrawGeoSphereHandler();
	if (bool checked = value)
	{
		connect(handler, Signal_Detached, &MainWindow::slotDrawHandlerDetached);
		handler->setAsset(_target);
		emit("apply-handler", handler);
	}
	else
	{
		disconnect(handler, Signal_Detached);
		handler->setAsset(BValue());
		emit("remove-handler", handler);
	}
	object->setAsset(handler);
}
void MainWindow::slotDrawCylinderButtonToggled(BObject* object, const BValue& value)
{
	static BHolder<DrawCylinderHandler> handler = new DrawCylinderHandler();
	if (bool checked = value)
	{
		connect(handler, Signal_Detached, &MainWindow::slotDrawHandlerDetached);
		handler->setAsset(_target);
		emit("apply-handler", handler);
	}
	else
	{
		disconnect(handler, Signal_Detached);
		handler->setAsset(BValue());
		emit("remove-handler", handler);
	}
	object->setAsset(handler);
}
void MainWindow::slotDrawCapsuleButtonToggled(BObject* object, const BValue& value)
{
	static BHolder<DrawCapsuleHandler> handler = new DrawCapsuleHandler();
	if (bool checked = value)
	{
		connect(handler, Signal_Detached, &MainWindow::slotDrawHandlerDetached);
		handler->setAsset(_target);
		emit("apply-handler", handler);
	}
	else
	{
		disconnect(handler, Signal_Detached);
		handler->setAsset(BValue());
		emit("remove-handler", handler);
	}
	object->setAsset(handler);
}
void MainWindow::slotDrawTubeButtonToggled(BObject* object, const BValue& value)
{
	static BHolder<DrawTubeHandler> handler = new DrawTubeHandler();
	if (bool checked = value)
	{
		connect(handler, Signal_Detached, &MainWindow::slotDrawHandlerDetached);
		handler->setAsset(_target);
		emit("apply-handler", handler);
	}
	else
	{
		disconnect(handler, Signal_Detached);
		handler->setAsset(BValue());
		emit("remove-handler", handler);
	}
	object->setAsset(handler);
}
void MainWindow::slotDrawTorusButtonToggled(BObject* object, const BValue& value)
{
	static BHolder<DrawTorusHandler> handler = new DrawTorusHandler();
	if (bool checked = value)
	{
		connect(handler, Signal_Detached, &MainWindow::slotDrawHandlerDetached);
		handler->setAsset(_target);
		emit("apply-handler", handler);
	}
	else
	{
		disconnect(handler, Signal_Detached);
		handler->setAsset(BValue());
		emit("remove-handler", handler);
	}
	object->setAsset(handler);
}
void MainWindow::slotDrawBillboardButtonToggled(BObject* object, const BValue& value)
{

}
void MainWindow::slotDrawTextualButtonToggled(BObject* object, const BValue& value)
{

}

void MainWindow::slotDrawHandlerDetached(BObject* object, const BValue& value)
{
	if (_drawCapsuleButton->asset() == object)
		_drawCapsuleButton->setChecked(false);
	else if (_drawConeButton->asset() == object)
		_drawConeButton->setChecked(false);
	else if (_drawCubeButton->asset() == object)
		_drawCubeButton->setChecked(false);
	else if (_drawCylinderButton->asset() == object)
		_drawCylinderButton->setChecked(false);
	else if (_drawSphereButton->asset() == object)
		_drawSphereButton->setChecked(false);
	else if (_drawGeoSphereButton->asset() == object)
		_drawGeoSphereButton->setChecked(false);
	else if (_drawTubeButton->asset() == object)
		_drawTubeButton->setChecked(false);
	else if (_drawTorusButton->asset() == object)
		_drawTorusButton->setChecked(false);
	else if (_drawBillboardButton->asset() == object)
		_drawBillboardButton->setChecked(false);
	else if (_drawTextualButton->asset() == object)
		_drawTextualButton->setChecked(false);
}

void MainWindow::adjustEvent(const BEvent& event)
{
	BMainWindow::adjustEvent(event);
}

void MainWindow::styleEvent(const BEvent& event)
{
	BMainWindow::styleEvent(event);
	const BStyle* style = event.value();
	_openButton->setIcon(style->icon("open"));
	_saveButton->setIcon(style->icon("save"));

	_importButton->setIcon(style->icon("import"));
	_exportButton->setIcon(style->icon("export"));
	_resetButton->setIcon(style->icon("reset"));

	_undoButton->setIcon(style->icon("undo"));
	_redoButton->setIcon(style->icon("redo"));
	_selectButton->setIcon(style->icon("select"));
	_moveButton->setIcon(style->icon("move"));
	_rotateButton->setIcon(style->icon("rotate"));
	_scaleButton->setIcon(style->icon("scale"));

	_drawConeButton->setIcon(style->icon("draw-cone"));
	_drawCubeButton->setIcon(style->icon("draw-cube"));
	_drawSphereButton->setIcon(style->icon("draw-sphere"));
	_drawGeoSphereButton->setIcon(style->icon("draw-geosphere"));
	_drawCylinderButton->setIcon(style->icon("draw-cylinder"));
	_drawCapsuleButton->setIcon(style->icon("draw-capsule"));
	_drawTubeButton->setIcon(style->icon("draw-tube"));
	_drawTorusButton->setIcon(style->icon("draw-torus"));
	_drawBillboardButton->setIcon(style->icon("draw-billboard"));
	_drawTextualButton->setIcon(style->icon("draw-textual"));

	_openButton->setTips(style->text("tips-open"));
	_saveButton->setTips(style->text("tips-save"));

	_importButton->setTips(style->text("tips-import"));
	_exportButton->setTips(style->text("tips-export"));
	_resetButton->setTips(style->text("tips-reset"));

	_undoButton->setTips(style->text("tips-undo"));
	_redoButton->setTips(style->text("tips-redo"));
	_selectButton->setTips(style->text("tips-select"));
	_moveButton->setTips(style->text("tips-move"));
	_rotateButton->setTips(style->text("tips-rotate"));
	_scaleButton->setTips(style->text("tips-scale"));

	_drawConeButton->setTips(style->text("tips-draw-cone"));
	_drawCubeButton->setTips(style->text("tipsdraw-cube"));
	_drawSphereButton->setTips(style->text("tipsdraw-sphere"));
	_drawGeoSphereButton->setTips(style->text("tipsdraw-geosphere"));
	_drawCylinderButton->setTips(style->text("tipsdraw-cylinder"));
	_drawCapsuleButton->setTips(style->text("tipsdraw-capsule"));
	_drawTubeButton->setTips(style->text("tipsdraw-tube"));
	_drawTorusButton->setTips(style->text("tipsdraw-torus"));
	_drawBillboardButton->setTips(style->text("tipsdraw-billboard"));
	_drawTextualButton->setTips(style->text("tipsdraw-textual"));

	freshMenuIcons(_itemMenu);
	BStringArray colorNames;
	style->colorNames(colorNames);
	for (int i = 0; i < colorNames.size(); i++)
	{
		const BString& name = colorNames[i];
		const BColor& color = style->color(name);
		BButton* button = new BButton(Graph_Square_Fill);
		button->setSizePolicy(Policy_Preferred);
		button->setColor(color);
		button->setTips(name);
		button->setName("basic");
		_colorGridLayout->insertWidget(button);
		connect(button, Signal_Clicked, &MainWindow::slotClearColorButtonClicked);
	}
}
